package com.parleys.activity;

import java.util.ArrayList;
import java.util.List;

import roboguice.inject.InjectExtra;
import roboguice.inject.InjectView;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Gallery;

import com.google.inject.Inject;
import com.parleys.R;
import com.parleys.adapter.GalleryImageAdapter;
import com.parleys.androidservice.ParleysMediaPlayer;
import com.parleys.domain.Channel;
import com.parleys.domain.Presentation;
import com.parleys.domain.PresentationAsset;
import com.parleys.domain.Space;
import com.parleys.helper.ApplicationConstants;
import com.parleys.helper.DownloadTask;
import com.parleys.service.intf.ParleysService;
import com.parleys.service.intf.PresentationAssetsService;

/**
 * Displays the slides linked to a presentation.
 * 
 * @author David Van Droogenbroeck
 * 
 */
public class GalleryActivity extends AbstractParleysActivity {

	private final static String TAG = GalleryActivity.class.getName();

	private List<PresentationAsset> imageAssets = new ArrayList<PresentationAsset>();

	private boolean updateGui = false;

	private boolean continuePrefetching = true;

	@InjectExtra(ApplicationConstants.ONLINE_ARG)
	private Boolean online;

	@InjectExtra(ApplicationConstants.SPACE_ARG)
	private Space space;

	@InjectExtra(ApplicationConstants.CHANNEL_ARG)
	private Channel channel;

	@InjectExtra(ApplicationConstants.PRESENTATION_ARG)
	private Presentation presentation;

	@InjectView(R.id.gallery)
	private Gallery gallery;

	@Inject
	private ParleysService parleysService;

	@Inject
	private PresentationAssetsService presentationAssetsService;

	public GalleryActivity() {
		setCustomTitleEnabled(false);
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.gallery_view);

		final List<PresentationAsset> allAssets = parleysService.getPresentationAssets(presentation.getId(), online);

		for (PresentationAsset pa : allAssets) {
			if (ApplicationConstants.IMAGE.equals(pa.getType())) {
				imageAssets.add(pa);
			}
		}

		// perform sanity check and take user away if needed
		// no need to continue from here if this fails
		if (!isImageOk()) {
			warnAndQuit();
		} else {

			gallery.setAdapter(new GalleryImageAdapter(this, imageAssets, channel.getAssetBaseURL(), presentation
					.getId(), presentationAssetsService));

			// if a user clicks and changes the current slide we dont want to have
			// any more automatic updates
			gallery.setOnTouchListener(new OnTouchListener() {

				@Override
				public boolean onTouch(View view, MotionEvent event) {
					updateGui = false;
					return false;
				}

			});

			// Performance tweak
			Runnable imagePrefetcher = new Runnable() {
				@Override
				public void run() {
					for (int count = Math.min(imageAssets.size(), 1); count < imageAssets.size() && continuePrefetching; count++) {
						Log.d(TAG, "Prefeteching image " + count);
						presentationAssetsService.getImage(space.getAssetBaseURL(), "presentations", presentation
								.getId(), imageAssets.get(count).getValue());
					}
				}
			};

			Thread thread = new Thread(imagePrefetcher);
			thread.setPriority(Thread.MIN_PRIORITY);
			thread.start();
			// End of performance tweak

		}

	}

	@Override
	protected void onStart() {
		super.onStart();
		new Handler().post(setFocusOnCurrentSlideOfTheTalk);
		updateGui = true;
	}

	protected void onStop() {
		super.onStop();
		updateGui = false;
		continuePrefetching = false;
	}

	private final Runnable setFocusOnCurrentSlideOfTheTalk = new Runnable() {

		@Override
		public void run() {
			if (updateGui && ParleysMediaPlayer.isPlaying()) {
				int currentPosition = ParleysMediaPlayer.getCurrentPosition();
				PresentationAsset slideToSelect = null;
				for (PresentationAsset imageAsset : imageAssets) {
					if (currentPosition > imageAsset.getCuepoint() * 1000) {
						slideToSelect = imageAsset;
					}
				}
				if (slideToSelect != null) {
					gallery.setSelection(imageAssets.indexOf(slideToSelect), true);
				}

			}

			new Handler().postDelayed(this, 5000);

		}
	};

	@Override
	public boolean onCreateOptionsMenu(final Menu menu) {

		MenuItem generalInfoMenuItem = menu.add(0, 0, 0, getString(R.string.general_info));
		generalInfoMenuItem.setIcon(android.R.drawable.ic_menu_info_details);

		if (online) {
			MenuItem previewChaptersMenuItem = menu.add(1, 1, 0, getString(R.string.preview_chapters));
			previewChaptersMenuItem.setIcon(android.R.drawable.ic_media_play);
			MenuItem downloadMenuItem = menu.add(2, 2, 0, getString(R.string.download));
			downloadMenuItem.setIcon(android.R.drawable.ic_menu_save);

			if (parleysService.isPresentationDownloaded(presentation.getId())) {
				menu.setGroupEnabled(2, false);
			}

		} else {
			MenuItem chaptersMenuItem = menu.add(1, 1, 0, getString(R.string.chapters));
			chaptersMenuItem.setIcon(android.R.drawable.ic_media_play);
		}
		return true;
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		MenuItem menuItem = menu.findItem(3);
		if (menuItem == null) {
			menuItem = menu.add(1, 3, 0, getString(R.string.pause));
		}
		ParleysMediaPlayer.initializePlayButton(menuItem, this.getApplicationContext());

		return true;
	}

	/* Handles item selections */
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case 0:
			Log.d(TAG, "First menu button pressed");
			gotoDetailActivity(space, channel, presentation, online);
			return true;
		case 1:
			Log.d(TAG, "Second menu button pressed");
			gotoChaptersActivity(space, channel, presentation, online);
			return true;
		case 2:
			Log.d(TAG, "Third menu button pressed");
			DownloadTask task = new DownloadTask(presentation, channel, space);
			getInjector().injectMembers(task);
			task.start();
			return true;
		case 3:
			Log.d(TAG, "Pause/Play menu button pressed");
			ParleysMediaPlayer.toggle(channel, presentation, online);
			return true;
		}
		return false;
	}

	/**
	 * Performs a sanity check on the first image of the slides
	 * 
	 * @return images is in an ok state
	 */
	private boolean isImageOk() {
		if (imageAssets.isEmpty()) {
			return false;
		}
		Bitmap bitmap = presentationAssetsService.getImage(channel.getAssetBaseURL(), "presentations", presentation
				.getId(), imageAssets.get(0).getValue());
		return bitmap != null && bitmap.getHeight() > 1;
	}

	private void warnAndQuit() {
		new AlertDialog.Builder(this) //
				.setIcon(android.R.drawable.ic_dialog_alert) //
				.setTitle(getString(R.string.no_images_title)) //
				.setMessage(getString(R.string.no_images_description)) //
				.setPositiveButton(getString(R.string.no_images_take_me_back), new DialogInterface.OnClickListener() {

					@Override
					public void onClick(DialogInterface dialog, int which) {
						GalleryActivity.this.finish();
					}

				}).show();
	}

}
